package cn.com.cetccst.compliancecheck.location;

import static com.amap.api.fence.GeoFenceClient.GEOFENCE_IN;
import static com.amap.api.fence.GeoFenceClient.GEOFENCE_OUT;
import static com.amap.api.fence.GeoFenceClient.GEOFENCE_STAYED;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;

import androidx.core.content.ContextCompat;

import com.amap.api.fence.GeoFence;
import com.amap.api.fence.GeoFenceClient;
import com.amap.api.fence.GeoFenceListener;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.DPoint;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

import cn.com.cetccst.datacenter.policy.fence.GFence;
import cn.com.cetccst.tools.log.CommonLogger;

public class GeoFencerExecutor {
    private static final String GEOFENCE_BROADCAST_ACTION = "cn.com.cetccst.cp.geofence";
    private static final String kFenceName = "CETECSE_CP_CHECK";

    private GeoFenceListener fenceListener;
    private final GeoFenceClient fenceClient;
    private GeoFence fence;

    public GeoFencerExecutor(Context context, IFenceListener listener) {
        AMapLocationClient.updatePrivacyShow(context, true, true);
        AMapLocationClient.updatePrivacyAgree(context, true);
        fenceClient = new GeoFenceClient(context);
        initFenceChangeListener(context, listener);
        initFence();
    }

    private void initFenceChangeListener(Context context, IFenceListener listener) {
        BroadcastReceiver fenceUpdateReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent == null) return;
                String action = intent.getAction();
                if (action == null || action.isEmpty()) return;

                Bundle bundle = intent.getExtras();
                if (bundle != null) {
                    if (listener != null && fence != null) {
                        listener.handleFenceStatusChanged(fence.getStatus());
                    }
                }
            }
        };
        IntentFilter filter = new IntentFilter();
        filter.addAction(GEOFENCE_BROADCAST_ACTION);
        ContextCompat.registerReceiver(context, fenceUpdateReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED);
    }

    private void initFence() {
        if (fenceListener != null) return;
        fenceListener = (list, errorCode, s) -> {
            if (errorCode == GeoFence.ADDGEOFENCE_SUCCESS) {
                CommonLogger.info("create geo fence ok");
                for (GeoFence fence : list) {
                    if (fence.getCustomId().equals(kFenceName)) {
                        GeoFencerExecutor.this.fence = fence;
                        CommonLogger.info("geo fence status:%d", fence.getStatus());
                        break;
                    }
                }
            } else {
                CommonLogger.info("create geo fence error: " + errorCode);
            }
        };

        fenceClient.setActivateAction(GEOFENCE_IN | GEOFENCE_OUT | GEOFENCE_STAYED);
        fenceClient.setGeoFenceListener(fenceListener);
        fenceClient.createPendingIntent(GEOFENCE_BROADCAST_ACTION);
    }

    public void addFences(GFence gFence) {
        removeFence();
        List<GFence.Area> areas = gFence.getAreas();
        if (areas != null) {
            for (GFence.Area area : areas) {
                String outline = area.getOutline();
                try {
                    JSONObject jsonObject = new JSONObject(outline);
                    JSONObject center = jsonObject.optJSONObject("center");
                    if (center != null) {
                        double latitude = center.optDouble("lat");
                        double longitude = center.optDouble("lng");
                        float radius = jsonObject.optInt("radius");
                        createCircleFence(new DPoint(latitude, longitude), radius);
                    }
                } catch (JSONException e) {
                    CommonLogger.error("geofence parse error", e);
                }
            }
        }
    }

    public int getFenceStatus() {
        return fence == null ? GeoFence.STATUS_UNKNOWN : fence.getStatus();
    }

    //TODO 目前仅支持一个围栏，后续如果支持多围栏再修改
    private void createCircleFence(DPoint center, float radius) {
        removeFence();
        fenceClient.addGeoFence(center, radius, kFenceName);
    }

    private void removeFence() {
        if (fence != null) {
            fenceClient.removeGeoFence(fence);
            fence = null;
        }
    }

    public interface IFenceListener {
        void handleFenceStatusChanged(int status);
    }
}